package com.example.boos.HttpUtil;

import android.util.Log;


import com.example.boos.context.ParameterizedTypeImp;
import com.example.boos.context.ResultMsg;
import com.example.boos.util.JsonUtil;
import com.google.gson.Gson;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.LinkedList;

public class MyGet {
    public static String tokenId = "";
    private static final String pre = "http://192.168.249.83:9905/";
    // 测试一下get请求
    private static  URL uurl = null;
    private static  HttpURLConnection connection;
    private static BufferedReader reader = null;
    private static JsonUtil jsonUtil = null;
    // 使用 HttpURLConnection
    public static Object doGet(String url){
        ResultMsg result = null;
        try {
            getUrlAndConnection(url);
            // 设置请求办法
            connection.setRequestMethod("GET");
            /*
            * 这边 还可以设置一下请求的消息头等信息，自己定义
            * */
            connection.connect();
            // 获取服务器返回的输入流，并从中提取信息
            InputStream in = connection.getInputStream();
            // 读取输入流
            reader = new BufferedReader(new InputStreamReader(in));
            StringBuilder response = new StringBuilder();
            String line ;
            while((line = reader.readLine()) != null){
                response.append(line);
            }
            Log.i("httpDemoGet",response.toString());
            // 解析后
            String genericClass = connection.getHeaderField("Generic-Class");
            // 处理一下字符串
            genericClass = handleString(genericClass);
            if(judge(genericClass)){
                // 需要进行处理
               result = (ResultMsg) parseJson(response.toString(),genericClass);
            }else{
                // 不需要进行处理
                result =(ResultMsg) getObjectOne(response.toString(), Class.forName(genericClass));
            }
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }finally {
            shutdown();
            if(result != null){
                return result.getData();
            }else{
                return result;
            }
        }

    }

    private static String handleString(String genericClass){
        String s = genericClass.replaceFirst("waimai", "boos");
        return s;
    }

    // 判断是否要处理
    public static boolean judge(String genericClass){
        return genericClass.contains("<");
    }

    static String setParam(Object param){
        Gson gson = new Gson();
        String s = gson.toJson(param);
        return s;
    }



    static Object parseJson(String response,String genericClass1) throws ClassNotFoundException {
        String genericClass = genericClass1.trim();
        // 解析 genericClass
        LinkedList<String> keys = new LinkedList<>();
        LinkedList<Object> values = new LinkedList<>();
        // 若字符串后面跟的是 < 。就将刚才的字符串入栈
        // 如果跟的是 逗号，就将刚才的字符串 和接下来的字符串 生成为 class对象，入 values栈
        // 如果 遇到 > 取出 valuse栈中的元素 和 keys的栈顶 形成一个 type对象，然后入 values栈。
        char[] chars = genericClass.toCharArray();
        int i =0;
        int length = chars.length;
        while(i < length){
            StringBuilder s = new StringBuilder();
            Character ttt = chars[i];
            if(Character.isLetter(chars[i])){
                // 开始遍历
                while(i < length && (chars[i]!='<' && chars[i]!= '>' && chars[i]!= ',' )){
                    s.append(chars[i]);
                    i++;
                }
                if( chars[i] =='<'){
                    keys.push(s.toString());
                    i++;
                }else if(chars[i] == '>'){
                    Class t = Class.forName(s.toString());
                    values.push(t);
                    // 取出values栈中所有的对象，生成type 和 keys 的栈顶
                    Class key = Class.forName(keys.pop());
                    LinkedList<Type> list = new LinkedList<>();
                    while(!values.isEmpty()){
                        list.push((Type)values.pop());
                    }
                    // 生成 type对象
                    Type type = new ParameterizedTypeImp(key, list.toArray(new Type[list.size()]));

                    values.push(type);
                    i++;
                }else{
                    // 遇到,
                    values.push(Class.forName(s.toString()));
                    i++;
                }
            }else if(chars[i] == '>'){
                Class key = Class.forName(keys.pop());
                LinkedList<Type> list = new LinkedList<>();
                while(!values.isEmpty()){
                    list.push((Type)values.pop());
                }
                // 生成type对象
                Type type = new ParameterizedTypeImp(key,list.toArray(new Type[list.size()]));
                values.push(type);
                i++;
            }else{
                i++;
            }
        }
        Type pop = (Type) values.pop();
        Class<? extends Type> aClass = pop.getClass();
        return getObject(response,pop);
    }


    static Object  getObject(String response,Type xclass){

        Gson gson = new Gson();
        // 获取到 ResultMsg data
        Type type =  new ParameterizedTypeImp(ResultMsg.class,new Type[]{xclass});
        ResultMsg result = gson.fromJson(response,type);
        return result;
    }

    static <T> ResultMsg<T> getObjectOne(String response,Class<T> xclass){
        Gson gson = new Gson();
        Type type = new ParameterizedTypeImp(ResultMsg.class,new Class[]{xclass});
        return gson.fromJson(response,type);
    }

     static void getUrlAndConnection(String url){
        try {

            uurl = new URL(pre+url);
            connection = (HttpURLConnection) uurl.openConnection();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
     static void shutdown(){
        if(connection != null){
            connection.disconnect();
            connection = null;
        }
        if(reader != null){
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            reader = null;
        }
        if(uurl != null){
            uurl = null;
        }
    }
}
